/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_Studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#pragma once

#include <node后端.h>

#include "ui节点面板.h"
#include "节点操作.h"
#include "节点构建.h"
#include "B_场景管理/操作记录.h"


/*struct S_节点连接线树 {
	std::map<uint32, S_节点连接线树*>	m_子集;
	std::vector<S_NodeLink*>			m_连接线;
};*/

class C_节点视口 : public C_Widget {
	//S_Surface2D* m_Surface;
	vec2						m_视图大小;
	std::vector<C_节点面板*>	m_被删除的节点面板;

protected:
	C_节点面板* m_当前绑定节点;

public:
	C_节点视口(S_UI创建环境& ctx, C_节点树* tree);
	~C_节点视口();

	
	C_Widget*					m_节点删除菜单;
	C_Widget*                   m_节点菜单;
	C_节点树*                   m_节点树后端;
	C_属性栏*					m_属性栏;
	
	S_Props						m_节点树容器;
	

	fp_从节点构建节点回调		mf_以节点构建节点;
	fp_节点构建_重构			mf_节点重构回调;
	FP_用名称构建节点面板		mf_名称构建节点面板;

	//GPU绘制数据
	//S_2D文本对象 m_节点面板名称文本对象;
	//S_2D文本对象 m_节点插座名称文本对象;
	//C_Widget*					m_滚动窗口;

	ui_绘制模板_自定义线		m_剪刀线绘制;
	ui_绘制模板_画预设图形		m_背景绘制;
	ui_绘制模板_画预设图形		m_背景线绘制;
	//ui_绘制模板_画预设图形		m_连接线绘制;
	ui_绘制模板_线段		    m_连接线绘制;
	
	
	ui_绘制模板_图标		m_节点面板图标绘制;
	ui_绘制模板_行文本绘制	m_节点面板文本绘制;
	ui_绘制模板_画预设图形	m_节点面板背景绘制;
	ui_绘制模板_线段		m_节点面板连接线绘制;


	ui_绘制模板_画预设图形	m_节点框绘制;
	ui_绘制模板_画预设图形	m_节点框边绘制;

	ui_绘制模板_画预设图形	m_节点区域绘制;
	ui_绘制模板_画预设图形	m_节点区域线绘制;
	S_板载缓存*				m_视口画布属性;

	ui_绘制模板_画预设图形	m_节点缩略图绘制;

	std::set<C_节点面板*>		m_焦点节点面板;
	

	static C_Widget* g多边形节点创建菜单;
	static C_Widget* g函数节点创建菜单;
	static C_Widget* g物体节点创建菜单;
	static C_Widget* g材质节点创建菜单;
	static C_Widget* g渲染节点创建菜单;
	static C_Widget* g着色器节点创建菜单;
	static C_Widget* g节点层级切换面板;
	


	void f_remove节点面板(std::vector<C_节点面板*>& nodes);
	void f_update插座绘制(C_节点面板* 节点面板);


	vec2 f_get边界();
	void f_update节点面板(C_Widget* w);
	void f_Scale();


	void f_连接线线尾拖动(vec2 beginLoc, vec2 endLoc, S_RGBA8UI c, uint32 ID = 0);
	void f_绘制对齐线(vec2 beginLoc, vec2 endLoc, S_RGBA8UI c, uint32 ID = 0);
	void f_连接线线尾拖动结束();



	void f_绑定节点树(C_节点树* tree, C_节点面板* root_plane = nullptr);
	void f_清除所有节点面板();
	//void f_绑定节点树(C_节点树* tree);
	C_节点面板* f_从节点后端创建节点面板(C_节点基类* node, uint32 ID);
	void		f_节点面板添加到节点视口(C_节点面板* plane, uint32 ID);

	void		f_面板组件添加到视口中(C_节点面板* panel);
	void		f_节点面板从节点视口移入回收站(C_节点面板* self);
	C_节点面板* f_回收面板组件();

};


E_事件是否传递 f_NodeView_浅拷贝节点到剪切板(C_Widget* self, uint8 状态);
E_事件是否传递 f_NodeView_从剪切板粘贴拷拷贝节点(C_Widget* self, uint8 状态);

E_事件是否传递 f_NodeView_深拷贝节点到剪切板(C_Widget* self, uint8 状态);
E_事件是否传递 f_NodeView_从剪切板粘贴深拷贝节点(C_Widget* self, uint8 状态);

E_事件是否传递 f_NodeView_关联拷贝节点(C_Widget* self, uint8 状态);
E_事件是否传递 f_NodeView_深度拷贝节点(C_Widget* self, uint8 状态);

E_事件是否传递 f_NodeView_快捷键_返回上级节点(C_Widget* self, uint8 状态);
E_事件是否传递 f_NodeView_打开返回上级节点面板(C_Widget* self, uint8 状态);
E_事件是否传递 f_NodeView_移动节点面板(C_Widget* self, uint8 状态);

E_事件是否传递 f_NodeView_节点添加到框(C_Widget* self, uint8 状态);
E_事件是否传递 f_NodeView_节点相交链接(C_Widget* self, uint8 状态);
E_事件是否传递 f_NodeView_节点移动对齐(C_Widget* self, uint8 状态);

E_事件是否传递 f_NodeView_节点从框中移出(C_Widget* self, uint8 状态);






void f_init节点视口(S_设备环境& ctx);

C_节点视口* f_NodeView_创建节点窗口(S_UI创建环境& ctx, C_节点树* tree);


void f_NodeView_节点回调事件初始化(C_节点面板* 节点面板);
void f_节点View_设置操作节点(C_节点基类* node, C_节点视口* view);
vec2 f_NodeView_get变换后坐标(const vec2& 变换前坐标, S_View属性* view);
vec2 f_NodeView_get变换前坐标(const vec2& 变换后坐标, S_View属性* view);

void f_NodeView_更新前选择节点();

void f_NodeView_添加节点面板到视口(C_节点视口* 节点视口, C_节点面板* 节点面板, bool 是否清除以前激活节点);
void f_NodeView_其他工作区添加面板到视口(C_Widget* w, bool 是否清除以前激活节点);
void f_NodeView_添加节点面板到视口(std::vector<C_节点面板*>& ws, bool 是否清除以前激活节点);
void f_NodeView_添加节点到视口(C_节点视口* 节点视口, std::vector<C_节点基类*>& nodes, bool 是否清除以前激活节点);


void f_NodeView_更新节点(C_节点视口* view);

std::vector<C_节点面板*> f_NodeView_拷贝节点(C_节点视口* view, std::vector<C_节点基类*>& 要拷贝的节点, bool 拷贝节点树);


void f_NodeView_添加激活节点(std::vector<C_节点面板*>& nodes, bool 是否清除以前);
void f_NodeView_清除激活节点(C_节点视口* view);
void f_NodeView_设置节点视口激活节点(std::vector<C_节点基类*>& nodes);
void on_NodeView_删除节点菜单项(C_Widget* self, const std::wstring name, uint16 id);
void on_NodeView_设置当前操作视口(C_节点树* t);
void on_NodeView_设置当前操作节点树(C_节点树* t);

C_节点树* f_NodeView_取以前操作节点树();
C_节点树* f_NodeView_取当前要操作的节点树();

void on_节点树列表_编辑名称(S_Props& prop);
void on_节点树列表_重构节点视口内节点(S_Props& prop);
bool f_NodeView_绑定节点视口弹出菜单(E_节点树类型 节点树类型, C_节点视口* view);


std::vector<C_节点面板*> f_NodeView_从节点添加节点面板到视口(C_节点基类* node, bool 是否清除以前激活节点);
void f_NodeView_设置节点面板局部添加位置(const vec2& 局部位置, bool 是否中心 = true);
//void f_PropUpdate_返回上一级节点树(S_Props& prop);
//void on_节点树列表_项改变(S_Props& prop, S_MapPtr& ptrItem, int32 操作类型);
//void f_NodeView_深拷贝节点(std::vector<C_节点基类*>& 节点面板, C_节点树* 节点视口);
//std::vector<C_节点面板*> f_NodeView_浅拷贝节点(C_节点视口* view, std::vector<C_节点基类*>& 要拷贝的节点);






class C_节点操作_添加节点 : public C_操作记录 {
public:
	void f_撤销();
	void f_重做();
};

class C_节点操作_删除节点 : public C_操作记录 {
	C_节点视口* m_View;
	std::vector<C_节点面板*>	m_节点面板;
	std::vector<S_NodeLink*>	m_断开的连接线;
public:
	C_节点操作_删除节点(C_节点视口* View, const std::vector<C_节点面板*>& Nodes);
	~C_节点操作_删除节点();

	void f_撤销();
	void f_重做();
};



class C_节点操作_选择节点 : public C_操作记录 {
public:
	void f_撤销();
	void f_重做();
protected:
	void f_记录();
};






struct S_关联拷贝节点剪切板 : public S_剪切板 {

	std::vector<C_节点基类*>			m_要拷贝的节点面板;
	//std::map<std::wstring, C_节点面板*>	m_新节点面板;
	//std::vector<S_节点链接线记录*>		m_节点链接线记录;
	std::vector<vec2>		m_节点中心坐标偏移;

	S_关联拷贝节点剪切板(std::set<C_节点面板*>& nodes);

	void f_复制();
	void f_粘贴();
};




struct S_深拷贝节点剪切板 : public S_剪切板 {

	std::vector<C_节点基类*>			m_要拷贝的节点面板;
	//std::map<std::wstring, C_节点面板*>	m_新节点面板;
	//std::vector<S_节点链接线记录*>		m_节点链接线记录;
	std::vector<vec2>		m_节点中心坐标偏移;

	S_深拷贝节点剪切板(std::set<C_节点面板*>& nodes);

	void f_复制();
	void f_粘贴();
};







